﻿using SvGame.Objects;
using System.Numerics;
using System.Security.Cryptography;
using System.Xml.Linq;

namespace SvGame.Logic;

public static partial class GameLogic
{
    public static int Perform敌单内外功(this IRole me, ConfigPerform conf, IRole opp)
    {
        if (Rd(me.StatusMax.Force) < 50)
        {
            return me.MessageError($"糟糕，没成功！");
        }
        if (conf.Args.Count < 3)
        {
            loger.Error($"Perform敌单内外功 {conf.Id} error 错误配置 Args");
            return 1;
        }
        int success_adj = conf.Args[0].ToInt();
        int damage_adj = conf.Args[1].ToInt();
        EPerformDamageType damage_type = (EPerformDamageType)conf.Args[2].ToInt();
        // 招式前描述
        if (!conf.DescPre.IsNullOrEmpty())
        {
            MessageVisionCombat(conf.DescPre, me, opp);
        }
        int 技能总等级 = 0;
        if (conf.Args.Count > 3)
        {
            for (int i = 3; i < conf.Args.Count; i++)
            {
                技能总等级 += me.SkillGetLevel(conf.Args[i]);
            }
        }


        // 判断成功
        if (!Perform敌单内外功CheckSuccess(me, opp, success_adj, 技能总等级))
        {
            MessageVisionCombat(conf.DescFail, me, opp);
            return 0;
        }

        // 获取伤害
        var damage = Perform敌单内外功GetDamage(me, opp, damage_adj);
        if (damage > 0)
        {
            ApplyDamage(me, opp, damage, damage_type, conf.DescSuccess);
        }
        else if (damage < 0)
        {
            MessageVisionCombat(conf.DescBack, me, opp);
            ApplyDamage(opp, me, -damage, damage_type, conf.DescBackSuccess);
        }
        else
        {
            MessageVisionCombat("#HIB#结果正好被$N以内力逼住，谁也没有吃亏。#NOR#", opp);
        }

        return 0;
    }
    public static bool Perform敌单内外功CheckSuccess(this IRole me, IRole opp, int success_adj, int 技能总等级)
    {
        long ap, dp;

        ap = 技能总等级;
        ap = (ap * ap * ap / 10);
        ap = ap * (1 + me.Exp / 500000);
        ap = ap + me.Exp;

        dp = opp.Exp;

        success_adj = Math.Clamp(success_adj, 20, 500);

        ap = ap * success_adj / 100;

        var debugmsg = $"Perform敌单内外功CheckSuccess me:{me.Name} ap:{ap} dp:{dp}";
        loger.Debug(debugmsg);

        if (Rd(100) > dp * 100 / (ap + dp))
        {
            return true;
        }

        return false;
    }
    public static int Perform敌单内外功GetDamage(this IRole me, IRole opp, int damage_adj)
    {
        long ap, dp;
        long damage;

        damage_adj = Math.Clamp(damage_adj, 50, 200);

        ap = Math.Min(me.StatusCur.Force, me.StatusMax.Force * 2);
        dp = Math.Min(opp.StatusCur.Force, opp.StatusMax.Force * 2);

        damage = (ap - dp) / 30 + Rd(me.StatusEff.Kee / 30) - Rd(opp.StatusEff.Kee / 30);
        damage += 3 * damage_adj / 100;

        damage = damage * damage_adj / 100;
        if (damage > 0)
        {
            damage += (damage * me.UsageGetLevel(EUsageType.基本内功) / 200);
        }
        else if (damage < 0)
        {
            damage += (damage * opp.UsageGetLevel(EUsageType.基本内功) / 200);
        }
        var debugmsg = $"Perform敌单内外功GetDamage me:{me.Name} ap:{ap} dp:{dp} damage:{damage}";
        loger.Debug(debugmsg);

        return (int)damage;
    }
}
